﻿/*
 * This software is the confidential and proprietary
 * information of NetBay
 * Such confidential information should not be disclosed
 * NetBay copyright(c) 2010
 */

#region Using
using System;
using System.Windows;
using System.IO;
using System.IO.IsolatedStorage;
using System.Text;
using System.Diagnostics;
using System.Reflection;
#endregion

namespace NetBay.Core.Silverlight.Log
{
    /// <summary>
    /// Class handle log functions
    /// </summary>
    public class Logger
    {
        #region Enum
        public enum Level
        {
            None = 0,
            Error,
            Warning,
            Debug,
            Verbose,
        }
        #endregion

        #region Constants
        private const int C_PadRightModule = 64;
        private const int C_MaxSizeFile = 995 * 1024;
        #endregion

        #region Private Members
        /// <summary>
        /// Name directory to store logs
        /// </summary>
        private static string m_sDirectoryNameToLog = @"Logs";
        /// <summary>
        /// Full name directory to store logs
        /// </summary>
        /// <remarks>Only used for OutOfBrowser functions</remarks>
        private static string m_sDirectoryFullNameToLog = @"c:\\temp\\Logs";
        /// <summary>
        /// Indicate the desired level of log
        /// </summary>
        private static Level m_oLevelLog = Level.Verbose;
        #endregion

        #region Properties
        #endregion

        #region Functions

        #region Publics
        /// <summary>
        /// Initialize this class
        /// </summary>
        public static void Init(Level p_oLevel)
        {
            // TODO : Do something to initialize class Logger
            m_oLevelLog = p_oLevel;
        }

        /// <summary>
        /// Write a message in file and display it in a MessageBox
        /// </summary>
        /// <param name="p_sToLog">message</param>
        public static void Display(string p_sToLog, Level p_oLevel)
        {
            // Check the level log
            if (p_oLevel > m_oLevelLog)
                return;
            string sModule = GetFullQualifiedName();
            // Log to File
            WriteCore(sModule, p_sToLog, p_oLevel);
            // Display the message
            MessageBox.Show(p_sToLog, sModule, MessageBoxButton.OK);
        }
        /// <summary>
        /// Write a message in file
        /// </summary>
        /// <param name="p_sToLog">message</param>
        public static void Write(string p_sToLog, Level p_oLevel)
        {
            WriteCore(GetFullQualifiedName(), p_sToLog, p_oLevel);
        }
        #endregion

        #region Private
        /// <summary>
        /// Write a message in file
        /// </summary>
        /// <param name="p_sToLog">message</param>
        private static void WriteCore(string p_sModule, string p_sToLog, Level p_oLevel)
        {
            // Check the level log
            if (p_oLevel > m_oLevelLog)
                return;

            // Log To File
            WriteToFile(p_sModule, p_sToLog);
        }

        /// <summary>
        /// Write a message in file 
        /// </summary>
        /// <param name="p_sToLog">message</param>
        private static void WriteToFile(string p_sModule, string p_sToLog)
        {
            try
            {
                //using (var store = IsolatedStorageFile.GetUserStoreForApplication())
                //{
                //    // Use a StringBuilder to construct output.
                //    StringBuilder sb = new StringBuilder();

                //    // Create a directories in the root.
                //    CreateDirectoryIfNeeded(store);

                //    // Create a file in MyLogs
                //    IsolatedStorageFileStream rootFile = store.OpenFile(System.IO.Path.Combine(m_sDirectoryNameToLog, Application.Current + ".log"), FileMode.OpenOrCreate);
                //    if (rootFile.Length > C_MaxSizeFile)
                //    {
                //        // TODO : handle when file is too big!
                //        MessageBox.Show(
                //            "File used to log:" + Environment.NewLine +
                //            /*store. + Environment.NewLine + */
                //            "is too big. Drop it!"
                //            );
                //    }
                //    // handle to log time
                //    string toLogDisk = AddTimeStamp(AppendModuleAndMessage(p_sModule, p_sToLog));
                //    // Write to disk
                //    byte[] abToLogDisk = System.Text.Encoding.UTF8.GetBytes(toLogDisk);
                //    rootFile.Seek(0, SeekOrigin.End);
                //    rootFile.Write(abToLogDisk, 0, abToLogDisk.Length);
                //    rootFile.Flush(true);
                //    rootFile.Close();
                //}

                
            }
            catch (Exception ex)
            {
                MessageBox.Show("Write(" + p_sToLog + ") exception : " + ex.Message);
            }
        }

        /// <summary>
        /// Create the log Directory
        /// </summary>
        /// <param name="p_oStore">IsolatedStorage File</param>
        private static void CreateDirectoryIfNeeded(IsolatedStorageFile p_oStore)
        {
            try
            {
                bool exist = false;
                string[] directories = p_oStore.GetDirectoryNames();
                if (directories != null)
                    foreach (string oItem in directories)
                    {
                        if (string.Equals(oItem, m_sDirectoryNameToLog) == true)
                        {
                            exist = true;
                            break;
                        }
                    }
                if (exist == false)
                    p_oStore.CreateDirectory(m_sDirectoryNameToLog);
            }
            catch (Exception ex)
            {
                MessageBox.Show("CreateDirectoryIfNeeded(" + p_oStore + ") exception : " + ex.Message);
            }
        }

        /// <summary>
        /// Write to the file
        /// </summary>
        /// <param name="p_sModule">Module</param>
        /// <param name="p_sToLog">The string to log</param>
        private static void WriteToFileOOB(string p_sModule, string p_sToLog)
        {
            try
            {
                // handle to log time
                string toLogDisk = AddTimeStamp(AppendModuleAndMessage(p_sModule, p_sToLog));
                // Write to File

                // HFE : TODO à réintégrer!!!!
                //using (dynamic fsoCom = ComAutomationFactory.CreateObject("Scripting.FileSystemObject"))
                //{
                //    dynamic file = fsoCom.CreateTextFile(System.IO.Path.Combine(m_sDirectoryFullNameToLog, Application.Current + ".log"), true);
                //    file.WriteLine(toLogDisk);
                //    file.Close();
                //}
            }
            catch (Exception ex)
            {
                MessageBox.Show("Write(" + p_sToLog + ") exception : " + ex.Message);
            }
        }

        /// <summary>
        /// Add a time stamp
        /// </summary>
        /// <param name="ps_sToLog">the string to log</param>
        /// <returns>The date</returns>
        private static string AddTimeStamp(string ps_sToLog)
        {
            DateTime dtNow = DateTime.Now;
            return dtNow.ToShortDateString() + " " + dtNow.ToLongTimeString() + "." + dtNow.Millisecond + " | " + ps_sToLog + Environment.NewLine;
        }
        private static string AppendModuleAndMessage(string module, string toLog)
        {
            string ret = "";
            if (string.IsNullOrEmpty(module) == false)
                ret += module.PadRight(C_PadRightModule) + " | ";
            if (string.IsNullOrEmpty(toLog) == false)
                ret += toLog;
            return ret;
        }
        /// <summary>
        /// Retreive Full qualified name of function call
        /// </summary>
        /// <returns>Full Qualified Name</returns>
        private static string GetFullQualifiedName()
        {
            StackFrame frame = new StackFrame(2);
            MethodBase method = frame.GetMethod();
            return method.ReflectedType.FullName + "." + method.Name;
        }
        #endregion

        #endregion
    }
}
